package org.darcy.youchat.activity;

import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.viewpager.widget.ViewPager;

import org.darcy.youchat.activity.home.SearchUserActivity;
import org.darcy.youchat.activity.home.WebViewActivity;
import org.darcy.youchat.utils.AppConst;
import org.darcy.youchat.R;
import org.darcy.youchat.activity.home.ScanActivity;
import org.darcy.youchat.activity.home.NewFriendActivity;
import org.darcy.youchat.activity.home.TeamChatCreateActivity;
import org.darcy.youchat.adapter.MainPagerAdapter;
import org.darcy.youchat.broadcast.AuthBroadcastReceiver;
import org.darcy.youchat.databinding.ActivityMainBinding;
import org.darcy.youchat.factory.PopupWindowFactory;
import org.darcy.youchat.fragment.BaseFragment;
import org.darcy.youchat.fragment.ContactsFragment;
import org.darcy.youchat.fragment.DiscoveryFragment;
import org.darcy.youchat.fragment.MeFragment;
import org.darcy.youchat.fragment.MessageFragment;
import org.darcy.youchat.nimsdk.NimAccountSDK;
import org.darcy.youchat.nimsdk.NimFriendSDK;
import org.darcy.youchat.nimsdk.NimSystemSDK;
import org.darcy.youchat.nimsdk.NimTeamSDK;
import org.darcy.youchat.nimsdk.NimUserInfoSDK;
import org.darcy.youchat.nimsdk.custom.CustomAttachParser;
import org.darcy.youchat.utils.LogUtils;
import org.darcy.youchat.utils.StringUtils;
import org.darcy.youchat.utils.UIUtils;

import com.netease.nimlib.sdk.InvocationFuture;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.StatusCode;
import com.netease.nimlib.sdk.friend.model.FriendChangedNotify;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SystemMessageType;
import com.netease.nimlib.sdk.msg.model.SystemMessage;
import com.netease.nimlib.sdk.team.model.Team;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 微信主界面
 */
public class MainActivity extends BaseActivity {

    /**
     * 视图绑定类 对象
     */
    private ActivityMainBinding binding;

    public static final int REQ_CLEAR_UNREAD = 100;

    private int exit = 0;
    private MessageFragment mMessageFragment;
    private ContactsFragment mContactsFragment;
    private DiscoveryFragment mDiscoveryFragment;
    private MeFragment mMeFragment;
    private List<BaseFragment> mFragments;

    private PopupWindow mPopupWindow;

    private List<SystemMessage> items = new ArrayList<>();//系统消息
    private static final boolean MERGE_ADD_FRIEND_VERIFY = true; // 是否要合并好友申请，同一个用户仅保留最近一条申请内容（默认不合并）
    private Set<String> addFriendVerifyRequestAccounts = new HashSet<>(); // 发送过好友申请的账号（好友申请合并用）

    private AuthBroadcastReceiver mAuthBroadcastReceiver;
    private Observer<StatusCode> mOnlineStatusObserver;

    public TextView mTvMessageCount;

    @Override
    public void init() {
        //注册登录出错广播接收者
        registerBroadcastReceiver();
        //监听在线状态
        observerLineStatus();
        //监听用户信息更新
        observeUserInfoUpdate();
        //监听好友关系的变化
        observeFriendChangedNotify();
        //监听群聊关系的变化
        observeTeamChangedNotify();
        //监听系统消息通知
        observeReceiveSystemMsg();
        // 注册自定义附件解析器到
        NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser());
    }

    @Override
    public void initView() {
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        setSupportActionBar(binding.mToolbar.toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("微信");
        binding.mToolbar.toolbar.setTitleTextColor(UIUtils.getColor(R.color.white));
        //默认选中第一个
        setTransparency();
        binding.tvMessagePress.getBackground().setAlpha(255);
        binding.tvMessageTextPress.setTextColor(Color.argb(255, 69, 192, 26));
        //设置ViewPager的最大缓存页面
        binding.vpContent.setOffscreenPageLimit(3);
    }

    @Override
    public void initData() {
        //创建4个界面的Fragment
        mFragments = new ArrayList<>();
        mMessageFragment = new MessageFragment();
        mContactsFragment = new ContactsFragment();
        mDiscoveryFragment = new DiscoveryFragment();
        mMeFragment = new MeFragment();
        mFragments.add(mMessageFragment);
        mFragments.add(mContactsFragment);
        mFragments.add(mDiscoveryFragment);
        mFragments.add(mMeFragment);
        //设置中间内容vp适配器
        binding.vpContent.setAdapter(new MainPagerAdapter(getSupportFragmentManager(), mFragments));
        binding.vpContent.setCurrentItem(0);
        //提示通讯录数据更新条目（未读数目）
        updateContactCount();
    }

    @Override
    public void initListener() {
        //tab页切换监听
        binding.llMessage.setOnClickListener(v -> {
            setTransparency();
            binding.vpContent.setCurrentItem(0, false);
            binding.tvMessagePress.getBackground().setAlpha(255);
            binding.tvMessageTextPress.setTextColor(Color.argb(255, 69, 192, 26));
        });
        binding.llContacts.setOnClickListener(v -> {
            setTransparency();
            binding.vpContent.setCurrentItem(1, false);
            binding.tvContactsPress.getBackground().setAlpha(255);
            binding.tvContactsTextPress.setTextColor(Color.argb(255, 69, 192, 26));
        });
        binding.llDiscovery.setOnClickListener(v -> {
            setTransparency();
            binding.vpContent.setCurrentItem(2, false);
            binding.tvDiscoveryPress.getBackground().setAlpha(255);
            binding.tvDiscoveryTextPress.setTextColor(Color.argb(255, 69, 192, 26));
        });
        binding.llMe.setOnClickListener(v -> {
            setTransparency();
            binding.vpContent.setCurrentItem(3, false);
            binding.tvMePress.getBackground().setAlpha(255);
            binding.tvMeTextPress.setTextColor(Color.argb(255, 69, 192, 26));
        });
        //设置vp的滑动监听事件，控制底部图标渐变
        binding.vpContent.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                //根据ViewPager滑动位置更改透明度
                int diaphaneity_one = (int) (255 * positionOffset);
                int diaphaneity_two = (int) (255 * (1 - positionOffset));
                switch (position) {
                    case 0:
                        binding.tvMessageNormal.getBackground().setAlpha(diaphaneity_one);
                        binding.tvMessagePress.getBackground().setAlpha(diaphaneity_two);
                        binding.tvContactsNormal.getBackground().setAlpha(diaphaneity_two);
                        binding.tvContactsPress.getBackground().setAlpha(diaphaneity_one);
                        binding.tvMessageTextNormal.setTextColor(Color.argb(diaphaneity_one, 153, 153, 153));
                        binding.tvMessageTextPress.setTextColor(Color.argb(diaphaneity_two, 69, 192, 26));
                        binding.tvContactsTextNormal.setTextColor(Color.argb(diaphaneity_two, 153, 153, 153));
                        binding.tvContactsTextPress.setTextColor(Color.argb(diaphaneity_one, 69, 192, 26));
                        break;
                    case 1:
                        binding.tvContactsNormal.getBackground().setAlpha(diaphaneity_one);
                        binding.tvContactsPress.getBackground().setAlpha(diaphaneity_two);
                        binding.tvDiscoveryNormal.getBackground().setAlpha(diaphaneity_two);
                        binding.tvDiscoveryPress.getBackground().setAlpha(diaphaneity_one);
                        binding.tvContactsTextNormal.setTextColor(Color.argb(diaphaneity_one, 153, 153, 153));
                        binding.tvContactsTextPress.setTextColor(Color.argb(diaphaneity_two, 69, 192, 26));
                        binding.tvDiscoveryTextNormal.setTextColor(Color.argb(diaphaneity_two, 153, 153, 153));
                        binding.tvDiscoveryTextPress.setTextColor(Color.argb(diaphaneity_one, 69, 192, 26));
                        break;
                    case 2:
                        binding.tvDiscoveryNormal.getBackground().setAlpha(diaphaneity_one);
                        binding.tvDiscoveryPress.getBackground().setAlpha(diaphaneity_two);
                        binding.tvMeNormal.getBackground().setAlpha(diaphaneity_two);
                        binding.tvMePress.getBackground().setAlpha(diaphaneity_one);
                        binding.tvDiscoveryTextNormal.setTextColor(Color.argb(diaphaneity_one, 153, 153, 153));
                        binding.tvDiscoveryTextPress.setTextColor(Color.argb(diaphaneity_two, 69, 192, 26));
                        binding.tvMeTextNormal.setTextColor(Color.argb(diaphaneity_two, 153, 153, 153));
                        binding.tvMeTextPress.setTextColor(Color.argb(diaphaneity_one, 69, 192, 26));
                        break;
                }

            }

            @Override
            public void onPageSelected(int position) {
                //如果是“通讯录”页被选中，则显示快速导航条
                if (position == 1) {
                    mContactsFragment.showQuickIndexBar(true);
                } else {
                    mContactsFragment.showQuickIndexBar(false);
                }
                //根据position刷新对应Fragment的数据
                mFragments.get(position).initData();
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (state != ViewPager.SCROLL_STATE_IDLE) {
                    //滚动过程中隐藏快速导航条
                    mContactsFragment.showQuickIndexBar(false);
                } else {
                    mContactsFragment.showQuickIndexBar(true);
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        new MenuInflater(this).inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.itemSearch:
                Intent intent = new Intent(this, SearchUserActivity.class);
                intent.putExtra(SearchUserActivity.SEARCH_TYPE, SearchUserActivity.SEARCH_USER_REMOTE);
                startActivity(intent);
                break;
            case R.id.itemMore:
                showMenu();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQ_CLEAR_UNREAD) {
            updateContactCount();
        }
    }

    @Override
    protected void onDestroy() {
        unRegisterBroadcastReceiver();
        super.onDestroy();
    }

    private void showMenu() {
        View menuView = View.inflate(this, R.layout.popup_menu_main, null);
        //发起群聊
        menuView.findViewById(R.id.itemCreateGroupChat).setOnClickListener(v -> {
            startActivity(new Intent(MainActivity.this, TeamChatCreateActivity.class));
            mPopupWindow.dismiss();
        });
        //添加朋友
        menuView.findViewById(R.id.itemAddFriend).setOnClickListener(v -> {
            startActivity(new Intent(MainActivity.this, NewFriendActivity.class));
            mPopupWindow.dismiss();
        });
        //扫一扫
        menuView.findViewById(R.id.itemScan).setOnClickListener(v -> {
            startActivity(new Intent(MainActivity.this, ScanActivity.class));
            mPopupWindow.dismiss();
        });
        //帮助与反馈
        menuView.findViewById(R.id.itemHelpAndFeedback).setOnClickListener(v -> {
            Intent intent = new Intent(MainActivity.this, WebViewActivity.class);
            intent.putExtra("url", AppConst.Url.HELP_FEEDBACK);
            startActivity(intent);
            mPopupWindow.dismiss();
        });
        mPopupWindow = PopupWindowFactory.getPopupWindowAtLocation(menuView, binding.vpContent, Gravity.RIGHT | Gravity.TOP, UIUtils.dip2Px(12), binding.mToolbar.toolbar.getHeight());
    }

    /**
     * 把press图片、文字全部隐藏(设置透明度)
     */
    private void setTransparency() {
        binding.tvMessageNormal.getBackground().setAlpha(255);
        binding.tvContactsNormal.getBackground().setAlpha(255);
        binding.tvDiscoveryNormal.getBackground().setAlpha(255);
        binding.tvMeNormal.getBackground().setAlpha(255);
        binding.tvMessagePress.getBackground().setAlpha(1);
        binding.tvContactsPress.getBackground().setAlpha(1);
        binding.tvDiscoveryPress.getBackground().setAlpha(1);
        binding.tvMePress.getBackground().setAlpha(1);
        binding.tvMessageTextNormal.setTextColor(Color.argb(255, 153, 153, 153));
        binding.tvContactsTextNormal.setTextColor(Color.argb(255, 153, 153, 153));
        binding.tvDiscoveryTextNormal.setTextColor(Color.argb(255, 153, 153, 153));
        binding.tvMeTextNormal.setTextColor(Color.argb(255, 153, 153, 153));
        binding.tvMessageTextPress.setTextColor(Color.argb(0, 69, 192, 26));
        binding.tvContactsTextPress.setTextColor(Color.argb(0, 69, 192, 26));
        binding.tvDiscoveryTextPress.setTextColor(Color.argb(0, 69, 192, 26));
        binding.tvMeTextPress.setTextColor(Color.argb(0, 69, 192, 26));
    }

    /**
     * 提示通讯录数据更新条目（未读数目）
     */
    public void updateContactCount() {
        //新好友、被邀请入群 未读消息数
        List<SystemMessageType> types = new ArrayList<>();
        types.add(SystemMessageType.AddFriend);
        types.add(SystemMessageType.TeamInvite);
        int unreadCount = NimSystemSDK.querySystemMessageUnreadCountByType(types);
        if (unreadCount > 0) {
            binding.tvContactCount.setVisibility(View.VISIBLE);
            binding.tvContactCount.setText(String.valueOf(unreadCount));
            return;
        } else {
            binding.tvContactCount.setVisibility(View.GONE);
        }
    }

    /**
     * 注册广播接收者
     */
    private void registerBroadcastReceiver() {
        //登录出错广播接收者
        mAuthBroadcastReceiver = new AuthBroadcastReceiver();
        registerReceiver(mAuthBroadcastReceiver, new IntentFilter(AuthBroadcastReceiver.ACTION));
    }

    /**
     * 反注册广播接收者
     */
    private void unRegisterBroadcastReceiver() {
        if (mAuthBroadcastReceiver != null) {
            unregisterReceiver(mAuthBroadcastReceiver);
            mAuthBroadcastReceiver = null;
        }
    }

    /**
     * 监听在线状态
     */
    private void observerLineStatus() {
        mOnlineStatusObserver = status -> {
            LogUtils.d("User status changed to: " + status);
            // 被踢出、账号被禁用、密码错误等情况，自动登录失败，需要返回到登录界面进行重新登录操作
            if (status.wontAutoLogin()) {
                //发广播通知
                Intent intent = new Intent();
                intent.setAction(AuthBroadcastReceiver.ACTION);
                intent.putExtra("status", status.getValue());
                sendBroadcast(intent);
            }
        };
        NimAccountSDK.onlineStatusListen(mOnlineStatusObserver, true);
    }

    /**
     * 监听用户信息更新
     */
    private void observeUserInfoUpdate() {
        NimUserInfoSDK.observeUserInfoUpdate((Observer<List<NimUserInfo>>) nimUser -> mMeFragment.initData(), true);
    }

    /**
     * 监听好友关系的变化
     */
    private void observeFriendChangedNotify() {
        NimFriendSDK.observeFriendChangedNotify((Observer<FriendChangedNotify>) friendChangedNotify -> {
            //更新通讯录数据
            mContactsFragment.initData();
        }, true);
    }

    /**
     * 监听群聊关系的变化
     */
    private void observeTeamChangedNotify() {
        NimTeamSDK.observeTeamRemove((Observer<Team>) team -> mMessageFragment.initData(), true);
    }

    /**
     * 监听系统消息通知
     */
    private void observeReceiveSystemMsg() {
        NimSystemSDK.observeReceiveSystemMsg((Observer<SystemMessage>) systemMessage -> {
            items.clear();
            List<SystemMessageType> types = new ArrayList<>();
            types.add(SystemMessageType.AddFriend);
            types.add(SystemMessageType.TeamInvite);
            InvocationFuture<List<SystemMessage>> listInvocationFuture = NimSystemSDK.querySystemMessageByType(types, 0, 100);
            listInvocationFuture.setCallback(new RequestCallback<List<SystemMessage>>() {
                @Override
                public void onSuccess(List<SystemMessage> param) {
                    if (!StringUtils.isEmpty(param)) {
                        items.addAll(param);

                        //TODO:查询系统消息后返回数据的顺序问题
                        SystemMessage del = null;
                        for (SystemMessage m : items) {
                            if (m.getMessageId() != systemMessage.getMessageId() &&
                                    m.getFromAccount().equals(systemMessage.getFromAccount()) && m.getType() == SystemMessageType.AddFriend) {
                                del = m;
                                break;
                            }
                        }
                        if (del != null) {
                            items.remove(del);
                            //删除本地系统消息中旧的一条
                            NimSystemSDK.deleteSystemMessage(del);
                        }
                        //提示通讯录数据更新条目
                        updateContactCount();
                        mContactsFragment.updateHeaderViewUnreadCount();
                        //更新本地新朋友数据库信息
                        if (systemMessage.getType() == SystemMessageType.AddFriend) {
                            NimUserInfoSDK.getUserInfoFromServer(systemMessage.getFromAccount(), null);
                        }
                    }
                }

                @Override
                public void onFailed(int code) {
                }

                @Override
                public void onException(Throwable exception) {
                }
            });
        }, true);
    }
}
